package io.renren.midplat.offerslook.affiliate;

import com.alibaba.fastjson.JSON;
import io.renren.common.exception.RRException;
import io.renren.common.main.MailService;
import io.renren.common.utils.*;
import io.renren.midplat.fuseclick.network.PushOffersByFuseClickServiceImpl;
import io.renren.midplat.offerslook.model.GetOfferModel;
import io.renren.midplat.offerslook.model.ResultModel;
import io.renren.modules.advertiser.entity.AdvertiserEntity;
import io.renren.modules.offer.entity.OfferEntity;
import io.renren.modules.offer.service.OfferService;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * offerslook获取广告通用组件
 *
 * @Description /aff/v1/batches/offers
 * @Author haijun.zhang@luckincoffee.com
 * @Date 2018-08-07 9:45
 */
@Service("pullOffersByOffersLookService")
public class PullOffersByOffersLookServiceImpl {

    @Autowired
    private OfferService offerService;
    /**
     * 日志
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(PullOffersByOffersLookServiceImpl.class);
    @Autowired
    private MailService mailService;

    public static final String urlParams=  "?type=personal&contains=description&filters[status][EQUAL_TO]=active";

    @Autowired
    @Qualifier("pushOffersByFuseClickService")
    private PushOffersByFuseClickServiceImpl pushOffersByFuseClickService;

    @Async
    public void serviceAsync(final AdvertiserEntity advertiser) {
        String batchNo = advertiser.getSspChannelId()+"-" + DateUtils.get12Time();
        Thread.currentThread().setName(batchNo);
        LOGGER.info("广告主："+advertiser.getSspChannelId()+" 开始拉取数据");
        LOGGER.info(advertiser.toString());
        UsernamePasswordCredentials key = new UsernamePasswordCredentials(advertiser.getUserName(), advertiser.getKey());

        try {

            int requestNum = 0;
            int limit = 30;

            String countResult = HttpUtils.doGet(advertiser.getDspApiDomain() + advertiser.getGetOffersUri() +urlParams+"&offset=1&limit=1",key);
            LOGGER.info("OffersLook 获取总数回参:{}",countResult);
            ResultModel countResultModel = JSON.parseObject(countResult, ResultModel.class);
            if (countResultModel.getCode() == 0) {
                GetOfferModel getOfferModel = JSON.parseObject(countResultModel.getData(), GetOfferModel.class);
                LOGGER.info("offer 总数：{}", getOfferModel.getTotalRows());
                if(advertiser.getRequestLimit()!=null && IntegerUtils.isNumeric(advertiser.getRequestLimit())){
                    limit =Integer.valueOf(advertiser.getRequestLimit());
                }
                requestNum = getOfferModel.getTotalRows()/limit +1;
            } else {
                throw new RRException("获取总数异常"+countResultModel.getCode()+"  "+countResultModel.getMessage());
            }

            //TODO
           //requestNum = 1;

            //线程沉睡1秒，访问太快了，人家会连接超时~~~~
            Thread.sleep(200);
            LOGGER.info("OffersLook 需要请求次数:" + requestNum);
            LOGGER.info("OffersLook request for start:");
            List<GetOfferModel.OfferAllBean> offerAllBeanList = new ArrayList<GetOfferModel.OfferAllBean>();

            for (int i = 1;i<=requestNum;i++){
                LOGGER.debug("OffersLook 第: " +i+ " 次开始");
                Map<String, String> params = new LinkedHashMap<>();
                params.put("offset", i+"");
                params.put("limit", advertiser.getRequestLimit()+"");
                String result = HttpUtils.doGet(advertiser.getDspApiDomain() + advertiser.getGetOffersUri() +urlParams+"&offset="+i+"&limit="+limit,key);
                LOGGER.debug(i+ "次回参:{}",result);

                ResultModel resultModel = JSON.parseObject(result, ResultModel.class);
                if (resultModel.getCode() == 0) {
                    GetOfferModel getOfferModel = JSON.parseObject(resultModel.getData(), GetOfferModel.class);
                    offerAllBeanList.addAll(getOfferModel.getOfferAll()) ;
                } else {
                    LOGGER.error(resultModel.getMessage());
                    throw new RRException("请求异常"+resultModel.getMessage());
                }
                Thread.sleep(200);
                LOGGER.debug("OffersLook 第: " +i+ " 次结束");
            }
            LOGGER.info("OffersLook request for end:");
            LOGGER.info("需要处理的数据总数:{}",offerAllBeanList.size());

            List<OfferEntity> offerEntityList = new ArrayList<OfferEntity>();
            transfer(offerAllBeanList,offerEntityList,batchNo,advertiser);
            LOGGER.debug("offerEntityList.size:{}",offerEntityList.size());
            if(offerAllBeanList.size()!=offerEntityList.size()){
                throw new RRException("数据不一致，offerAllBeanList.size:" + offerAllBeanList.size() +"offerEntityList.size:"+offerEntityList.size());
            }else{
                //调用保存广告操作
                offerService.pull(offerEntityList,batchNo,advertiser);
            }
            LOGGER.info("当前线程:"+Thread.currentThread().getName());
            LOGGER.info("沉睡1秒，等事物提交？？？？");
            Thread.sleep(1000);
            LOGGER.info("广告主："+advertiser.getSspChannelId()+" 上传FuseClick数据开始");
            pushOffersByFuseClickService.service(advertiser);
            LOGGER.info("广告主："+advertiser.getSspChannelId()+" 上传FuseClick数据");
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
            LOGGER.error("广告主："+advertiser.getSspChannelId()+" 开始拉取数据 ERROR");
            mailService.sendOffersPullErrorMail("广告主："+advertiser.getSspChannelId()+" 开始拉取数据 ERROR:",""+e.getMessage());
            e.printStackTrace();
        }
        LOGGER.info("广告主："+advertiser.getSspChannelId()+" 结束拉取数据");
    }

    private void transfer(List<GetOfferModel.OfferAllBean> offerAllBeanList,List<OfferEntity> offerEntityList,String batchNo,AdvertiserEntity advertiser){
        for(GetOfferModel.OfferAllBean offerAllBean:offerAllBeanList){
            GetOfferModel.OfferAllBean.OfferBean offerBean = offerAllBean.getOffer();
            OfferEntity offerEntity = new OfferEntity();
            offerEntity.setDspChannelId(advertiser.getDspChannelId());
            offerEntity.setSspChannelId(advertiser.getSspChannelId());
            offerEntity.setDspOfferId(offerBean.getId());
            offerEntity.setName(offerBean.getName());
            offerEntity.setDescription(offerBean.getDescription());
            offerEntity.setStatus(offerBean.getStatus());
            offerEntity.setCategory(offerBean.getCategory());
            offerEntity.setOfferApproval(offerBean.getOffer_approval());
            offerEntity.setOfferApprovalMsg(offerBean.getOffer_approval_msg());
            offerEntity.setTrackingLink(offerBean.getTracking_link());
            offerEntity.setEndDate(DateUtils.formatBySecs(offerBean.getEnd_date()));
            offerEntity.setPricingType(offerBean.getPricing_type());
            offerEntity.setPayout(offerBean.getPayout());
            offerEntity.setPercentPayout(offerBean.getPercent_payout());
            offerEntity.setCurrency(offerBean.getCurrency());
            offerEntity.setPreviewUrl(offerBean.getPreview_url());
            offerEntity.setConversionProtoco(offerBean.getConversion_protocol()+"");
            offerEntity.setConversionProtocolMsg(offerBean.getConversion_protocol_msg());
            offerEntity.setThumbnail(offerBean.getThumbnail());
            offerEntity.setOfferGeo(offerAllBean.getOffer_geo());
            offerEntity.setOfferVbt(offerAllBean.getOffer_vbt());
            offerEntity.setOfferEvent(offerAllBean.getOffer_event());
            offerEntity.setOfferPostback(offerAllBean.getOffer_postback());
            offerEntity.setOfferPlatform(offerAllBean.getOffer_platform());
            offerEntity.setOfferCreative(offerAllBean.getOffer_creative());
            offerEntity.setOfferCap(offerAllBean.getOffer_cap());
            offerEntity.setUpdateTime(new Date());
            offerEntity.setBatchNo(batchNo);
            offerEntity.setPushStatus("Active");
            offerEntityList.add(offerEntity);
        }
    }

}
